/*
文件操作
        文件指针
            FILE *fp;
        打开文件
            fp=fopen(文件路径，打开方式);
            当文件打开失败会返回NULL给fp，否则返回的是非NULL值
            文件路径：
                    相对路径：相对于当前工程下的路径
                    绝对路径：linux:以根目录   windows:盘符
            打开方式：
                    读       :r
                    写       :w
                    追加写   :a
                    可读可写 :+
                文件类型：t：文本文件   b：二进制文件
                打开方式可以和文件类型进行组合   ：rb  rt  ab  at  wb  wt
                    r:只读方式打开   文件不存在就会打开失败
                    w:只写方式打开   文件不存在就会新建一个文件，如果文件存在 会刷新掉文件的内容
                    a:追加写方式打开文件，如果文件存在不会新建文件读写指针追加在末尾，如果文件不存在会新建文件
            关闭文件
                    fclose(文件指针)
            文件读写操作函数
                                写        读
                    字符读写   fputc     fgetc
                    字符串读写 fputs     fgets  fgets函数遇到换行会结束
                    格式化读写 fprintf   fscanf
                二进制/模块化读写fwrite   fread   成对使用

            printf(格式控制，输出表列)；//数据输出到屏幕终端 双引号里面的内容是原样输出
            sprintf(字符指针，格式控制，输出表列)；//数据格式化转换到字符串中
    文件写： fprintf(文件指针，格式控制，输出表列)；//输出输出到文件指针指向的文件
            scanf(格式控制，地址表列);//从键盘获取输入的数据存入指定变量中  遇到空格或者回车结束停止读取
    文件读： fscanf(文件指针，格式控制，地址表列)；//从文件指针指向的文件中获取数据存入到指定变量中
            sscanf(字符指针，格式控制，地址表列)；//将字符串数据格式化转换到指定变量中

            文件位置函数
                    rewind(文件指针)：//将文件读写位置指针移至文件首位置
                    fseek(文件指针，移动长度，移动的起始位置)
                            长度：<0  往前移动   >0 往后移动
                            起始位置：
                                    SEEK_SET:首位置    0
                                    SEEK_CUR:当前位置  1
                                    SEEK_END:末尾位置  2
            文件末尾
                    符号：EOF  文件末尾的符号
                    函数 feof(文件指针)：如果到了文件末尾返回非0值  如果没到末尾返回0值
            rename:重命名文件名
            remove:删除文件
*/
#include <stdio.h>
void fgets_fputs(void)
{
    char s1[50]={"2408班C语言课程"},s2[50]={'\0'};
    //文件指针
    FILE *fp;
    fp=fopen("ct.txt","w+");//可读可写的方式打开文件
    if(!fp)
    {
        printf("文件打开失败\n");
        return;
    }
    printf("文件打开成功\n");
    //向文件写入一串数据
    fputs(s1,fp);
    //将文件读写指针移至文件首位置
    //rewind(fp);
    //seek(fp,0L,0);//从文件的首位置移动了0个字节
    fseek(fp,4L,SEEK_SET);//从文件首位置移动4个字节
    //从文件中读取一串数据
    fgets(s2,sizeof(s2),fp);//从fp指向的文件中读sizeof(s2)-1个字节到s2中 如果数据不足指定长度 遇到回车或者文件结尾就结束
    printf("s2:%s\n",s2);
    //关闭文件
    fclose(fp);
}
void fprintf_fscanf(void)
{
    struct stu
    {
        int class;
        char name[20];
        int age;
        double h;
    }zs;

    FILE *fp;//文件指针
    fp=fopen("格式读写.txt","w+");//以可读可写的方式打开一个文件，如果存在刷新数据，不存在会新建
    //判断文件是否打开成功
    if(!fp)
    {
        printf("file open faild\n");
        return;
    }
    fprintf(fp,"%d %s %d %lf",2408,"wanghong",250,1.74);
    //文件读写指针移到文件的首位置
    rewind(fp);
    //从文件中将数据读到结构体变量中
    fscanf(fp,"%d%s%d%lf",&zs.class,zs.name,&zs.age,&zs.h);
    //关闭文件
    fclose(fp);
    printf("zs的信息 班级:%d 姓名:%s 年龄:%d 身高:%lfm\n",zs.class,zs.name,zs.age,zs.h);
}
void fread_fwrite(void)
{
    struct stu
    {
        int class;
        char name[20];
        int age;
        double h;
    }zs={2408,"wanghong",250,1.49},wh;
    //文件指针 打开文件
    FILE *fp=fopen("模块化读写.txt","w+");
    if(!fp)
    {
        printf("file open faild\n");
        return;
    }
    //向文件写入数据
    fwrite(&zs,sizeof(struct stu),1,fp);//从zs结构体变量中向文件写入1个sizeof(zs)大小的数据
    //移至首位置
    fseek(fp,0,0);
    //从文件中读数据
    fread(&wh,sizeof(struct stu),1,fp);
    //关闭文件
    fclose(fp);
    printf("wh的信息 班级:%d 姓名:%s 年龄:%d 身高:%lfm\n",wh.class,wh.name,wh.age,wh.h);
}
void fread_fwrite2(void)
{
    struct stu
    {
        int class;
        char name[20];
        int age;
        double h;
    }zs[2]={{2408,"wanghong",250,1.49},{5438438,"wanghong",250,1.49}},wh[2];
    //文件指针 打开文件
    FILE *fp=fopen("模块化读写.txt","w+");
    if(!fp)
    {
        printf("file open faild\n");
        return;
    }
    // //方法1
    // for(int i=0;i<2;i++){
    //     //向文件写入数据
    //     fwrite(&zs[i],sizeof(struct stu),1,fp);//从zs结构体变量中向文件写入1个sizeof(zs)大小的数据
    // }
    //方法2
    fwrite(zs,sizeof(struct stu),2,fp);//从zs结构体变量中向文件写入2个sizeof(zs)大小的数据
    //移至首位置
    fseek(fp,0,0);
    for(int i=0;i<2;i++)
    {
        //从文件中读数据
        fread(&wh[i],sizeof(struct stu),1,fp);
    }
    //关闭文件
    fclose(fp);
    for(int i=0;i<2;i++)
    {
        printf("wh[%d]的信息 班级:%d 姓名:%s 年龄:%d 身高:%lfm\n",i,wh[i].class,wh[i].name,wh[i].age,wh[i].h);
    }
}
void add_test(void)
{
    FILE *fp=fopen("add_tets.txt","a+");
    if(!fp)
    {
        printf("file open faild\n");
        return;
    }
    //写数据
    fputc('b',fp);
    rewind(fp);
    char ch;
    ch=fgetc(fp);
    fclose(fp);
    printf("ch:%c\n",ch);
}

int main(void)
{
    //fgets_fputs();
    //fprintf_fscanf();
    //fread_fwrite();
    fread_fwrite2();
    add_test();
    return 0;
}

int fgetc_fputc(void)
{
    char ch;
    //定义一个文件指针
    FILE *fp;
    //相对路径
    //fp=fopen("ct.c","r");//以只读方式打开
    //fp=fopen("ct.c","w");//以只写方式打开
    //绝对路径
    fp=fopen("/home/student/temp.txt","w");
    if(!fp)//(fp=NULL)
    {
        printf("文件打开失败\n");
        return 0;
    }
    printf("以写方式打开文件成功\n");

    //向文件写入单个字符
    fputc('a',fp);
    fputc('b',fp);
    //关闭文件
    fclose(fp);

    fp=fopen("/home/student/temp.txt","r");
    if(!fp)//(fp=NULL)
    {
        printf("文件打开失败\n");
        return 0;
    }
    printf("以读方式打开文件成功\n");

    //向文件读取字符
    ch=fgetc(fp);
    printf("ch:%c\n",ch);
    //关闭文件
    fclose(fp);
    return 0;
}